use proc_macro::TokenStream;
use quote::quote;
use syn::{ItemFn, parse_macro_input};

#[proc_macro_attribute]
pub fn test_with_ctx(_args: TokenStream, input: TokenStream) -> TokenStream {
    let input_fn = parse_macro_input!(input as ItemFn);

    let fn_vis = &input_fn.vis;
    let fn_async = &input_fn.sig.asyncness;
    let fn_name = &input_fn.sig.ident;
    let fn_inputs = &input_fn.sig.inputs;
    let fn_output = &input_fn.sig.output;
    let block = &input_fn.block;

    let expanded = quote! {
        #[tokio::test]
        #fn_vis #fn_async fn #fn_name(#fn_inputs) #fn_output {
            // 问题分析：执行单元测试时，报错找不到config.toml文件。
            // 这个问题的根本原因是工作目录（working directory）不同导致的。
            
            // main函数运行时：
            // 通过 cargo run 启动
            // 工作目录是项目根目录（stock-quant/）
            // config.toml 文件位于项目根目录
            // fs::canonicalize("config.toml") 能够找到文件
            // 
            // 测试函数运行时：
            // 通过 cargo test 启动
            // 工作目录可能是 target/debug/deps/ 或其他测试相关目录
            // 相对路径 "config.toml" 无法找到文件
            
            // 获取工作区根目录
            let manifest_dir = env!("CARGO_MANIFEST_DIR");
            let workspace_root = std::path::Path::new(manifest_dir)
                .parent()  // 假设当前 crate 在工作区的子目录中
                .unwrap_or_else(|| std::path::Path::new(manifest_dir));
        
            std::env::set_current_dir(workspace_root).expect("Failed to change directory");
            
            sq_config::init();
            sq_wecom::init().await;
            sq_tushare::init();
            sq_gpt::init();
            let _guard = sq_log::init();
            
            #block

            assert_eq!(true, true);
        }
    };

    TokenStream::from(expanded)
}
